import os
from utils.common import CommonUtils
import re
import os

class BaseMigrator:
    def __init__(self, mysql_db, kingbase_db, migration_config, logger, task_name):
        self.mysql_db = mysql_db
        self.kingbase_db = kingbase_db
        self.migration_config = migration_config
        self.logger = logger
        self.task_name = task_name
        self.target_schema = migration_config.get('target_schema', '')
        
        # 初始化报告目录
        self.reports_dir = os.path.join('reports', self.task_name)
        CommonUtils.ensure_directory_exists(self.reports_dir)
        
        # PostgreSQL/KingbaseES兼容的数据类型映射
        self.type_mapping = {
            # 整数类型
            'int': 'integer',
            'tinyint': 'smallint',
            'smallint': 'smallint',
            'mediumint': 'integer',
            'bigint': 'bigint',
            'int unsigned': 'bigint',  # MySQL无符号整数映射到更大的整数类型
            'tinyint unsigned': 'integer',
            'smallint unsigned': 'integer',
            'mediumint unsigned': 'bigint',
            'bigint unsigned': 'numeric',
            
            # 浮点数类型
            'float': 'float',
            'double': 'double precision',
            'decimal': 'decimal',
            'numeric': 'numeric',
            
            # 字符串类型
            'char': 'char',
            'varchar': 'varchar',
            'text': 'text',
            'tinytext': 'text',
            'mediumtext': 'text',
            'longtext': 'text',
            
            # 日期时间类型
            'date': 'date',
            'time': 'time',
            'datetime': 'timestamp',
            'timestamp': 'timestamp',
            'year': 'integer',
            
            # 二进制类型
            'binary': 'bytea',
            'varbinary': 'bytea',
            'tinyblob': 'bytea',
            'mediumblob': 'bytea',
            'longblob': 'bytea',
            'blob': 'bytea',
            
            # 特殊类型
            'enum': 'varchar',  # 将enum映射为varchar并保留枚举值作为注释
            'set': 'varchar',   # 将set映射为varchar
            'json': 'jsonb',    # JSON类型映射到jsonb
            'geometry': 'geometry',  # 空间类型
        }
        
    def _convert_data_type(self, mysql_type):
        """
        转换MySQL数据类型到PostgreSQL/KingbaseES兼容的数据类型
        """
        # 转换为小写以确保大小写不敏感
        mysql_type = mysql_type.lower()
        
        # 处理无符号类型 - 更健壮的处理方式
        if 'unsigned' in mysql_type:
            # 提取基本类型（去掉unsigned）
            base_type_part = mysql_type.replace('unsigned', '').strip()
            
            # 检查是否有完整的类型映射
            if f'{base_type_part} unsigned' in self.type_mapping:
                converted_type = self.type_mapping[f'{base_type_part} unsigned']
                return converted_type
            
            # 提取基本类型名称
            base_type = base_type_part.split('(')[0].strip()
            
            # 对于decimal/numeric类型的无符号处理
            if base_type in ['decimal', 'numeric']:
                # PostgreSQL/KingbaseES没有unsigned decimal类型，但可以使用CHECK约束
                # 这里我们仍然返回decimal/numeric类型，但不包含unsigned关键字
                # 提取参数部分
                param_part = ''
                if '(' in base_type_part:
                    param_part = base_type_part[base_type_part.find('('):]
                return f"{base_type}{param_part}"
            
            # 对于其他可能的无符号类型
            if base_type in self.type_mapping:
                return self.type_mapping[base_type]
            
            # 默认处理
            return base_type_part
        
        # 提取基本类型和参数部分
        base_type = mysql_type.split('(')[0].strip()
        param_part = None
        if '(' in mysql_type:
            param_part = mysql_type[mysql_type.find('('):]
        
        # 检查是否为整数类型，直接返回不带参数的类型
        if base_type in ['int', 'integer', 'smallint', 'mediumint', 'bigint', 'tinyint']:
            if base_type in self.type_mapping:
                return self.type_mapping[base_type]  # 直接返回不带参数的映射类型
            return base_type  # 如果没有映射，返回基本类型
        
        # 查找映射的类型
        if base_type in self.type_mapping:
            converted_type = self.type_mapping[base_type]
            
            # 保留其他类型的参数（如长度）
            if param_part:
                # 处理特殊情况：enum和set类型的参数
                if base_type in ['enum', 'set']:
                    # 提取枚举值并添加为注释
                    enum_values = param_part
                    converted_type = f"{converted_type}(255)"
                # 对于文本类型，处理方式不变
                elif base_type in ['text', 'tinytext', 'mediumtext', 'longtext']:
                    # 不添加任何长度参数
                    pass
                elif base_type == 'varchar':
                    # 对于varchar类型，长度翻倍
                    # 提取长度值
                    length_match = re.search(r'\(\s*(\d+)\s*\)', param_part)
                    if length_match:
                        original_length = int(length_match.group(1))
                        doubled_length = original_length * 2
                        converted_type = f"{converted_type}({doubled_length})"
                    else:
                        # 如果无法提取长度，使用原始参数部分
                        converted_type = f"{converted_type}{param_part}"
                else:
                    # 对于其他类型，保留参数部分
                    converted_type = f"{converted_type}{param_part}"
            
            return converted_type
        
        # 如果没有找到映射，返回原始类型
        self.logger.warning(f"未找到MySQL类型 '{mysql_type}' 的映射，使用原始类型")
        return mysql_type
    
    def _handle_default_value(self, column_def, column_default, column_type):
        """
        处理默认值，确保兼容PostgreSQL/KingbaseES语法
        """
        # 处理NULL默认值
        if column_default == 'NULL':
            return column_def + " DEFAULT NULL"
        
        # 处理CURRENT_TIMESTAMP或类似的时间函数
        timestamp_funcs = ['current_timestamp', 'now()', 'localtimestamp']
        if isinstance(column_default, str) and any(func in column_default.lower() for func in timestamp_funcs):
            # PostgreSQL的CURRENT_TIMESTAMP不需要引号
            return column_def + " DEFAULT CURRENT_TIMESTAMP"
        
        # 处理字符串类型的默认值
        string_types = ['varchar', 'char', 'text']
        if any(string_type in column_type for string_type in string_types):
            # 确保字符串默认值被正确引号包裹，处理转义字符
            if isinstance(column_default, str):
                # 转义单引号
                escaped_default = column_default.replace("'", "''")
                return column_def + f" DEFAULT '{escaped_default}'"
            else:
                return column_def + f" DEFAULT '{column_default}'"
        
        # 处理数值类型的默认值
        numeric_types = ['integer', 'smallint', 'bigint', 'float', 'double', 'decimal', 'numeric']
        if any(numeric_type in column_type for numeric_type in numeric_types):
            return column_def + f" DEFAULT {column_default}"
        
        # 默认处理方式
        if isinstance(column_default, str):
            escaped_default = column_default.replace("'", "''")
            return column_def + f" DEFAULT '{escaped_default}'"
        else:
            return column_def + f" DEFAULT {column_default}"